/**
 * 同轴多元素的mixins,用来提取,文字驱动轴,音频驱动轴,和背景音乐轴相同部分
 * */

import LineItem from '@veditor/components/timeLine/components/lineItem.vue';
import { debounce } from 'lodash';
import WaveSurfer from 'wavesurfer.js';
import { calcText, musicCanvas } from '@veditor/components/timeLine/js/workerOptimize';
import { judgeAudioTypeOk, renderCanvasByOffScreen } from '@veditor/components/timeLine/js/tools';
export default {
  components: {
    LineItem,
  },
  props: {
    timelineItem: {
      required: true,
      type: Object,
    },
  },
  computed: {
    sliderArr() {
      return this.timelineItem.sliderArr;
    },
    isToMore() {
      const NUMBER = 20;
      return this.sliderArr.length > NUMBER;
    },
    renderType() {
      const { timelineItem } = this;
      const { name, musicSrc, audioSrc } = timelineItem;
      if (name === 'textDrive') {
        return 'wavesurfer';
      } else {
        const src = name === 'bgMusic' ? musicSrc : audioSrc;
        return judgeAudioTypeOk(src) ? 'wavesurfer' : 'arraybuffer';
      }
    },
  },
  mounted() {
    this.init = debounce(this.init, Number('100'));
    this.observeResize();
    this.timelineItem.onVideoDuration = this.init; // 注册一个坑位函数
  },
  data() {
    return {
      renderArr: [],
      observe: null,
      wavesurferObjArr: [],
    };
  },
  methods: {
    init() {
      this.$nextTick(() => {
        const { name } = this.timelineItem;
        this.closeWaveSurfer();
        if (name === 'doubleDrive') {
          this.initDoubleDrive();
        } else if (name === 'textDrive') {
          this.initTextDrive();
        } else if (this.renderType === 'wavesurfer') {
          this.initByWaveSurfer();
        } else {
          this.initByArrayBuffer();
        }
      });
    },
    // 根据wavesurfer进行初始化
    async initByWaveSurfer() {
      const { name, musicSrc, audioSrc } = this.timelineItem;
      const src = name === 'bgMusic' ? musicSrc : audioSrc;
      const canvasList = this.$refs.canvasRef;
      for (const canvasListKey in canvasList) {
        if (canvasList.hasOwnProperty(canvasListKey)) {
          this.initWaveSurfer(canvasList[canvasListKey], src, Number('26'));
        }
      }
    },
    // textDrive单独的初始化方法
    async initTextDrive() {
      const el = this.$refs.lineItemRef?.$el;
      if (!el) {
        return;
      }
      const canvasList = this.$refs.canvasRef;
      const imageBitTextArr = await this.renderTextCanvas(); // 文本canvas的绘制
      if (!imageBitTextArr) {
        return;
      }
      for (const index in canvasList) {
        if (canvasList.hasOwnProperty(index)) {
          // 绘制频谱图
          const canvas = canvasList[index];
          const blobSrc = this.timelineItem.sliderArr[index].url;
          this.initWaveSurfer(canvas, blobSrc, Number('13'));
          // 绘制文本
          const { width, height } = canvas.getBoundingClientRect();
          const canvas1 = this.$refs.canvasTextRef[index];
          renderCanvasByOffScreen(canvas1, imageBitTextArr[index], width, height);
        }
      }
    },
    // 老的初始化逻辑,根据二进制数据绘制
    async initByArrayBuffer() {
      const el = this.$refs.lineItemRef.$el;
      if (!el) {
        return;
      }
      const { width } = el.getBoundingClientRect();
      const columns = el.querySelector('.columns');
      if (columns) {
        const { offsetWidth, offsetHeight } = columns;
        const renderArr = await this.timelineItem.renderSpectrum(width);
        this.renderArr = renderArr;
        const imageBitMap = await this.renderCanvasWorker(offsetWidth, offsetHeight, renderArr);
        const canvasList = this.$refs.canvasRef;
        for (const canvasListKey in canvasList) {
          const canvas = canvasList[canvasListKey];
          Object.assign(canvas, { width: offsetWidth, height: offsetHeight });
          const ctx = canvas.getContext('2d');
          ctx.clearRect(0, 0, offsetWidth, offsetHeight);
          ctx.drawImage(imageBitMap, 0, 0);
        }
      }
    },
    // 绘制双人数字人驱动轴
    async initDoubleDrive() {
      const el = this.$refs.lineItemRef?.$el;
      if (!el) {
        return;
      }
      let textDriveIndex = 0;
      const textCanvasArr = await this.renderDoubleTextCanvas(); // 这里拿到了文本驱动绘制的列表
      if (!textCanvasArr) {
        return;
      }
      const canvasList = this.$refs.canvasRef;
      const canvasTextList = this.$refs.canvasTextRef;
      const { sliderArr } = this.timelineItem;
      sliderArr.forEach((item, index) => {
        const { mode, url } = item; // src:文本驱动的音频,url:是音频驱动
        const canvas = canvasList[index];
        if (mode === 'text') {
          const canvasText = canvasTextList[textDriveIndex];
          const { width, height } = canvasText.getBoundingClientRect();
          const canvasTextData = textCanvasArr[textDriveIndex++];
          renderCanvasByOffScreen(canvasText, canvasTextData, width, height);
          this.initWaveSurfer(canvas, url, Number('13'));
        } else {
          this.initWaveSurfer(canvas, url, Number('26'));
        }
      });
    },
    // 处理页面大小改变
    handleResize() {
      this.init(); // 这里单独对文本驱动轴更新
    },
    // 监听页面大小改变,重新计算页面和所有元素
    observeResize() {
      // 文本驱动轴和旧的绘制需要自适应
      this.observe = new ResizeObserver(() => {
        this.handleResize();
      });
      this.observe.observe(this.$refs.lineItemRef.$el);
    },
    initWaveSurfer(canvasItem, src, renderHeight) {
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      const gradient = ctx.createLinearGradient(0, Number('26'), 0, 0);
      gradient.addColorStop(0, '#22785f');
      gradient.addColorStop(Number('0.45'), '#22785f');
      gradient.addColorStop(Number('0.45'), '#AB973C');
      gradient.addColorStop(Number('0.75'), '#AB973C');
      gradient.addColorStop(Number('0.75'), '#b64b43');
      gradient.addColorStop(Number('0.95'), '#b64b43');
      const wavesurfer = WaveSurfer.create({
        container: canvasItem,
        waveColor: gradient,
        progressColor: gradient,
        height: renderHeight,
        barWidth: 3,
        barGap: 1,
        backend: 'MediaElement',
        mediaControls: false,
        audioRate: 1,
        cursorWidth: 0,
        barAlign: 'bottom',
        autoCenter: true,
        normalize: true,
      });
      wavesurfer.load(src);
      this.wavesurferObjArr.push(wavesurfer);
    },
    renderCanvasWorker(width, height, renderArr) {
      return new Promise(resolve => {
        const renderCanvas = new Worker(musicCanvas);
        renderCanvas.postMessage({
          width,
          height,
          renderArr,
          pixel: window.devicePixelRatio || 1,
        });
        renderCanvas.onmessage = e => {
          resolve(e.data);
          renderCanvas.terminate();
        };
        renderCanvas.onerror = e => {
          console.log(`web worker绘制canvas报错${e}`);
          renderCanvas.terminate();
        };
      });
    },
    // 绘制文本canvas的worker
    renderTextCanvasWorker(sliderArr) {
      const emptyData = sliderArr.filter(item => !item.width || !item.height);
      return new Promise(resolve => {
        if (emptyData.length) {
          resolve(null);
        }
        const workerControl = new Worker(calcText);
        workerControl.postMessage({
          sliderArr,
        });
        workerControl.onmessage = e => {
          resolve(e.data);
          workerControl.terminate();
        };
        workerControl.onerror = e => {
          console.log(`web worker绘制文本canvas报错${e}`);
          workerControl.terminate();
          resolve(null);
        };
      });
    },
    closeWaveSurfer() {
      this.wavesurferObjArr.forEach(item => {
        item && item.destroy();
      });
      this.wavesurferObjArr = [];
    },
  },
  beforeDestroy() {
    if (this.observe && this.$refs.lineItemRef.$el) {
      this.observe.unobserve(this.$refs.lineItemRef.$el);
    }
  },
};
